package com.example.demo.common.dto;


import com.example.demo.common.constant.CodeConst;
import io.micrometer.core.instrument.util.StringUtils;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.data.domain.Page;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 响应信息主体
 */
@ApiModel("返回结果")
public class R<T> implements Serializable {

    @ApiModelProperty("返回信息")
    private String msg = "success";
    @ApiModelProperty("返回状态")
    private int code = 0;
    @ApiModelProperty("返回数据")
    private T data;
    @ApiModelProperty("附加属性")
    private Map<String, Object> properties = new LinkedHashMap<>();

    private R() {
        super();
    }

    public static R<Object> build() {
        return new R<>();
    }

    public static <T> R<T> build(Class<T> clazz) {
        return new R<T>();
    }

    public static <T> R<List<T>> buildArray(Class<T> clazz) {
        return new R<List<T>>();
    }

    public static <T> R<Page<T>> buildPage(Class<T> clazz) {
        return new R<Page<T>>();
    }

    public R<T> successed(T data) {
        return successed(data, msg);
    }

    public R<T> successed(T data, String message) {
        this.setCode(CodeConst.SUCCESS);
        if (data != null) {
            this.data = data;
        }
        if (StringUtils.isBlank(message)) {
            message = "操作成功";
        }
        this.msg = message;
        return this;
    }

    public R<T> failed() {
        return failed(null, null, null);
    }

    public R<T> failed(CodeConst code) {
        return failed(code, null, null);
    }

    public R<T> failed(String message) {
        return failed(null, message, null);
    }

    public R<T> failed(Throwable throwable) {
        return failed(null, null, throwable);
    }

    public R<T> failed(CodeConst code, String message) {
        return failed(code, message, null);
    }

    public R<T> failed(CodeConst code, String message, Throwable throwable) {
        if (code == null) {
            code = CodeConst.FAIL;
        }
        this.setCode(code);
        if (throwable != null && StringUtils.isBlank(message)) {
            message = throwable.getMessage();
        }
        if (StringUtils.isBlank(message)) {
            message = "服务器异常";
        }
        this.setMsg(message);
        return this;
    }

    public T getData() {
        return data;
    }

    private R setData(T data) {
        this.data = data;
        return this;
    }

    public int getCode() {
        return code;
    }

    private R<T> setCode(CodeConst code) {
        this.code = code.getSymbol();
        return this;
    }

    public String getMsg() {
        return msg;
    }

    private R<T> setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    public Map<String, Object> getProperties() {
        return properties;
    }

    public R<T> setProperties(Map<String, Object> properties) {
        this.properties = properties;
        return this;
    }

    public R<T> setProperties(String name, Object value) {
        if (this.properties == null) {
            this.properties = new LinkedHashMap<>();
        }
        this.properties.put(name, value);
        return this;
    }
}
